package beer.coder.imageviewer;

import beer.coder.imageviewer.handler.ImageViewDraggedHandler;
import beer.coder.imageviewer.handler.ImageViewFitHandler;
import beer.coder.imageviewer.handler.ImageViewZoomHandler;
import javafx.scene.Cursor;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

/**
 * TODO
 *
 * @author amath0312
 * @version 1.0
 * @date 2020-11-01 16:14
 */
public class ImageViewer extends ImageView {

  protected double originFitWidth;
  protected double originFitHeight;
  protected double factor;

  /**
   * 添加parent后可执行此方法，初始化时间监听.
   */
  public void initHandlers() {
    //图片拖拽
    ImageViewDraggedHandler draggedHandler = new ImageViewDraggedHandler(this);
    this.setOnMousePressed(draggedHandler);
    this.setOnMouseDragged(draggedHandler);
    this.setOnMouseReleased(draggedHandler);

    //自动缩放
    ImageViewFitHandler fitHandler = new ImageViewFitHandler(this);
    this.setOnMouseClicked(fitHandler);
    this.getParent().setOnMouseClicked(fitHandler);

    //鼠标滚轮缩放
    ImageViewZoomHandler zoomHandler = new ImageViewZoomHandler(this);
    this.setOnScroll(zoomHandler);
    this.getParent().setOnScroll(zoomHandler);

    //设置鼠标指针
    this.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> {
      if (e.getButton() == MouseButton.PRIMARY) {
        this.setCursor(Cursor.CLOSED_HAND);
      }
    });
    this.addEventHandler(MouseEvent.MOUSE_RELEASED, e -> {
      if (e.getButton() == MouseButton.PRIMARY) {
        this.setCursor(Cursor.OPEN_HAND);
      }
    });
  }

  public void loadImage(Image image, double fitWidth, double fitHeight) {
    setLayoutX(0);
    setLayoutY(0);
    setFitWidth(fitWidth);
    setFitHeight(fitHeight);
    setSmooth(true);
    setImage(image);
    resetZoom();
  }

  public double getOriginFitWidth() {
    return originFitWidth;
  }

  public double getOriginFitHeight() {
    return originFitHeight;
  }

  public double getFactor() {
    return factor;
  }


  public void zoom(double delta) {
    this.factor = this.factor + delta;
    setFitWidth(originFitWidth * factor);
    setFitHeight(originFitHeight * factor);
    setLayoutX(getLayoutX() - originFitWidth * delta / 2);
    setLayoutY(getLayoutY() - originFitHeight * delta / 2);
  }

  public void resetZoom() {
    this.factor = 1.0d;
    this.originFitWidth = getFitWidth();
    this.originFitHeight = getFitHeight();
    this.factor = 1.0d;
  }
}
